/**
 * @description 数据存储
*/

import Model from '../../../core/model/model.js'
import parser from '../service/parser.js'

class Store extends Model {
  /**
   * @function 构造方法
  */
  constructor ({state = {}, pipe = {}} = {}) {
    super()
    // 初始化仓库
    this.state = state || {}
    // 数据列表
    this.state.list = []
    // 初始化处理器
    this.pipe = pipe || {}
    // 监测状态
    this._watchClean()
  }

  /**
   * @function 取数据
   * @param {any} key // 键名
   * @return {any}
  */
  getItem (key) {
    let value = null
    // key处理
    key = this._toKey(key)
    // 查找
    this.state.list.forEach(item => {
      if (item.key === key) {
        value = item.value
        return false
      }
    })

    return value
  }

  /**
   * @function 存数据
   * @param {any} key // 键名
   * @param {any} value // 键值
   * @param {Object} options // 配置对象
  */
  setItem (key, value, options) {
    options = options || {}
    let isCache = true
    // 数据解析
    let solve = typeof options.solve === 'function' ? options.solve : this.solve
    value = solve(value, options.dataType)
    // 数据验证
    let valid = options.valid
    if (valid !== true && valid !== 1) {
      valid = typeof options.valid === 'function' ? options.valid : this.valid
      isCache = valid(value, options.dataType)
    }
    // 不缓存
    if (!isCache) {
      return false
    }
    // key处理
    key = this._toKey(key)
    // 空键
    if (key === '') {
      return false
    }

    // 保存值
    let hasKey = false
    this.state.list.forEach(item => {
      if (item.key === key) {
        hasKey = true
        item.deploy = Object.assign(
          {}, item.deploy || {}, options || {}
        )
      }
    })
    // 新增
    if (!hasKey) {
      this.state.list.push({
        key: key,
        value: value,
        deploy: Object.assign({}, options || {})
      })
    }
  }

  /**
   * @function 数据解析
   * @param {any} data // 数据
   * @param {any} dataType // 数据类型
   * @return {any}
  */
  solve (data, dataType) {
    return parser.parse(data)
  }

  /**
   * @function 数据验证是否可缓存
   * @param {any} key1 // 键名1
   * @param {any} key2 // 键名2
   * @return {Boolean}
  */
  valid (data, dataType) {
    let result = true
    if (dataType) {
      dataType = String(type).toLowerCase().trim()
      // 对象类型
      if (
        (dataType === 'json' || dataType === 'object') ||
        (typeof data !== 'object' || !data)
      ) {
        result = false
      }
      // 数组类型
      else if (dataType === 'array' && !Array.isArray(data)) {
        result = false
      }
    }

    return result
  }

  /**
   * @function 生成Key
   * @param {any} key // 键名
   * @return {String}
  */
  _toKey (key) {
    if (key && typeof key === 'object') {
      key = JSON.stringify(key)
    }
    return String(key)
  }

  /**
   * @function 清除无效数据
  */
  _watchClean () {
    // 遍历配置
    this.state.list.forEach(node => {
      let item = node.deploy || {}
      let expires = parseInt(item.expires)
      expires = isNaN(expires) ? 365 * 24 * 60 * 60 * 1000 : expires
      if (expires + item.startTime <= (new Date).getTime()) {
        // 清除无效数据
        this.clean(node.key)
      }
    })
    // 循环监测
    setTimeout(() => {
      this._watchClean()
    }, 500)
  }

  /**
   * @function 清除无效数据
   * @param {any} key // 键名
  */
  clean (key) {
    this.state.list = this.state.list.filter(item => {
      return item.key === key
    })
  }
}

export default Store